# !/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===========================
@Time : 2022/8/27 0027 14:07
@Author : 测试开发工程师
@File : 15. case_table.py
@Software: PyCharm
============================
"""

import yaml
from flask import request, Flask
from flask_restx import Resource, Api, Namespace
from apitest.Test_frame.utils.log_utils import logger

from flask_sqlalchemy import SQLAlchemy
# 实例化 app 对象
from sqlalchemy import *

app = Flask(__name__)

with open("./data.yaml") as f:
    result = yaml.safe_load(f)
    username = result.get('database').get('username')
    password = result.get('database').get('password')
    server = result.get('database').get('server')
    db = result.get('database').get('db')

app.config['SQLALCHEMY_DATABASE_URI'] = f'mysql+pymysql://{username}:{password}@{server}/{db}?charset=utf8'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
# SQLAlchemy 绑定 app
db = SQLAlchemy(app)


# 数据库设计
# 创建用例表
class TestCase(db.Model):
    # 表名
    __tablename__ = 'testcase'
    # 用例 id，用例的唯一标识字段
    id = db.Column(Integer, primary_key=True)
    # 用例的标题 或者 文件名,限定 80 个字符，不为空并且唯一
    case_title = db.Column(String(80), nullable=False, unique=True)
    # 备注
    remark = db.Column(String(120))


# 接口设计
api = Api(app)
# 用例的命名空间
case_ns = Namespace('case', description='用例管理')


@case_ns.route("")
class TestCaseServer(Resource):
    # 定义 swagger 接口文档   args形式  可以传 id， 也可以不传
    #  id 可以为空。为空时，查询出所有内容
    # 不传 id，就是返回 全部记录
    # 传 id : 返回 对应的查询记录。未查到，返回空列表
    get_paresr = api.parser()
    get_paresr.add_argument('id', type=int, location='args')

    @case_ns.expect(get_paresr)
    def get(self):
        """
        测试用例的查找
        @return:
        """
        case_id = request.args.get('id')
        logger.info(f'接受到的参数<======={case_id}')
        if case_id:
            # 如果不为空，查询操作
            case_data = TestCase.query.filter_by(id=case_id).first()
            if case_data:
                datas = [{'id': case_data.id, 'case_title': case_data.case_title, 'remark': case_data.remark}]
            else:
                datas = []

        else:
            # 如果为空，返回所有记录
            case_datas = TestCase.query.all()
            datas = [{'id': case_data.id, 'case_title': case_data.case_title, 'remark': case_data.remark} for case_data
                     in case_datas]
        return datas

    # 定义 swagger 接口文档   json形式
    post_paresr = api.parser()
    post_paresr.add_argument('id', type=int, required=True, location='json')
    post_paresr.add_argument('case_title', type=str, required=True, location='json')
    post_paresr.add_argument('remark', type=str, location='json')

    @case_ns.expect(post_paresr)
    def post(self):
        """
        测试用例的新增
        @return:
        """
        # 获取请求数据
        case_data = request.json
        logger.info(f'接收到的参数<====== {case_data}')
        case_id = case_data.get('id')
        # 查询数据库，查看是否有记录 。 TestCase 数据库表
        exists = TestCase.query.filter_by(id=case_id).first()
        logger.info(f'查询表结果：{exists}')
        # 如果不存在，则添加这条记录到数据库中。存在，不执行新增操作，直接返回 40001 错误码
        if not exists:
            testcase = TestCase(**case_data)
            logger.info(f'将要存储的内容为<========{testcase}')
            db.session.add(testcase)
            db.session.commit()
            return {'code': 0, 'msg': f'case id{case_id} success add'}
        else:
            return {'code': 40001, 'msg': 'case is exists'}

    # 定义 swagger 接口文档   json形式
    put_paresr = api.parser()
    put_paresr.add_argument('id', type=int, required=True, location='json')
    put_paresr.add_argument('case_title', type=str, required=True, location='json')
    put_paresr.add_argument('remark', type=str, location='json')

    # id 是主键，不能修改
    @case_ns.expect(put_paresr)
    def put(self):
        """
        测试用例的修改
        @return:
        """
        case_data = request.json
        logger.info(f'接受到的参数<===={case_data}')
        case_id = case_data.get('id')
        # 查询数据库，查看是否有记录
        exists = TestCase.query.filter_by(id=case_id).first()
        logger.info(f'查询表结果：{exists}')
        # 如果存在，进行修改。不存在，返回 {'code':40002}
        if exists:
            case_data1 = {}
            case_data1['case_title'] = case_data.get('case_title')
            case_data1['remark'] = case_data.get('remark')
            TestCase.query.filter_by(id=case_id).update(case_data)
            db.session.commit()
            return {'code': 0, 'msg': f'case id{case_id} success change to {case_data1}'}
        else:
            return {'code': 40002, 'msg': 'case is not exists '}

    # 定义 swagger 接口文档   json形式
    delete_paresr = api.parser()
    delete_paresr.add_argument('id', type=int, required=True, location='json')

    @case_ns.expect(delete_paresr)
    def delete(self):
        """
        测试用例的删除
        @return:
        """
        case_data = request.json
        case_id = case_data.get('id')
        logger.info(f'接受到的参数id<========{case_id}')
        exists = TestCase.query.filter_by(id=case_id).first()
        if exists:
            TestCase.query.filter_by(id=case_id).delete()
            db.session.commit()
            return {'code': 0, 'msg': f'case id {case_id} succsee delete'}
        else:
            return {'code': 40002, 'msg': 'case is not exists'}


api.add_namespace(case_ns, '/testcase')

if __name__ == '__main__':
    db.create_all()
    app.run(debug=True)
